package com.bjpowernode.service.impl;

import com.bjpowernode.constant.Constants;
import com.bjpowernode.entity.TActivityRemark;
import com.bjpowernode.entity.TRole;
import com.bjpowernode.entity.TUser;
import com.bjpowernode.entity.TUserDO;
import com.bjpowernode.mapper.TRoleMapper;
import com.bjpowernode.mapper.TUserMapper;
import com.bjpowernode.query.BaseQuery;
import com.bjpowernode.query.UserPwdQuery;
import com.bjpowernode.query.UserQuery;
import com.bjpowernode.service.UserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private TUserMapper tUserMapper;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private TRoleMapper tRoleMapper;

    @Override
    public PageInfo<TUser> getUserPage(Integer current) {
        //1.设置PageHelper (第一个参数是查第几页，第二个参数每页查多少条数据)
        PageHelper.startPage(current, Constants.PAGE_SIZE);

        //2.查询数据库表的数据
        List<TUser> list = tUserMapper.selectUserPage(new BaseQuery());

        //3.封装分页数据到PageInfo
        PageInfo<TUser> info = new PageInfo<>(list);

        //4.返回PageInfo对象
        return info;
    }

    /**
     * spring security从数据库查询用户进行登录的方法
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        TUser tUser = tUserMapper.selectUserByLoginAct(username);
        if (tUser == null) {
            throw new UsernameNotFoundException("登录账号不存在");
        }

        //查询用户的角色
        List<TRole> tRoleList = tRoleMapper.selectByUserId(tUser.getId());
        List<String> stringRoleList = new ArrayList<>();
        tRoleList.forEach(tRole -> {
            stringRoleList.add(tRole.getRole());
        });
        //把用户的角色List设置到用户对象中
        tUser.setStringRoleList(stringRoleList);

        return tUser;
    }

    @Override
    public TUser getUserById(Integer userId) {
        return tUserMapper.selectByPrimaryKey(userId);
    }

    @Override
    public Boolean checkLoginPwd(Integer userId, String loginPwd) {
        TUser tUser = tUserMapper.selectByPrimaryKey(userId);
        //密码比较
        return passwordEncoder.matches(loginPwd, tUser.getLoginPwd());
    }

    @Override
    public int updateLoginPwd(UserPwdQuery userPwdQuery) {
        //后端也需要验证一下，验证参数对不对
        //1、验证原始密码对不对
        TUser tUser = tUserMapper.selectByPrimaryKey(userPwdQuery.getUserId());
        boolean match = passwordEncoder.matches(userPwdQuery.getLoginPwd(), tUser.getLoginPwd());
        if (!match) { //如果原始密码不正确
            throw new RuntimeException("您输入的元素登录密码有误");
        }

        //2、验证两次输入的密码是否一致
        if (!userPwdQuery.getNewLoginPwd().equals(userPwdQuery.getReNewLoginPwd())) {
            throw new RuntimeException("您两次输入的登录密码不一致");
        }

        //3、更新数据库中用户的登录密码
        TUser user = new TUser();
        user.setId(userPwdQuery.getUserId());
        user.setLoginPwd(passwordEncoder.encode(userPwdQuery.getNewLoginPwd()));
        user.setEditTime(new Date());
        user.setEditBy(userPwdQuery.getUserId()); //当前登录人的id
        return tUserMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public int saveUser(UserQuery userQuery) {
        TUser tUser = new TUser();

        //对象属性值的复制，把userQuery对象里面的属性值复制到tUser对象的属性中
        //复制的条件：源对象 和 目标对象 里面的属性字段名要相同，属性的字段类型也相同，才可以复制
        BeanUtils.copyProperties(userQuery, tUser);

        //密码加密
        tUser.setLoginPwd(passwordEncoder.encode(userQuery.getLoginPwd()));
        //创建时间
        tUser.setCreateTime(new Date());
        //创建人
        TUser authUser = (TUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Integer currentLoginUserId = authUser.getId();
        tUser.setCreateBy(currentLoginUserId);

        return tUserMapper.insertSelective(tUser);
    }

    @Override
    public int updateUser(UserQuery userQuery) {
        TUser tUser = new TUser();

        //对象属性值的复制，把userQuery对象里面的属性值复制到tUser对象的属性中
        //复制的条件：源对象 和 目标对象 里面的属性字段名要相同，属性的字段类型也相同，才可以复制
        BeanUtils.copyProperties(userQuery, tUser);

        //密码加密
        if (StringUtils.hasText(userQuery.getLoginPwd())) {
            tUser.setLoginPwd(passwordEncoder.encode(userQuery.getLoginPwd()));
        }
        //编辑时间
        tUser.setEditTime(new Date());
        //编辑人
        TUser authUser = (TUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Integer currentLoginUserId = authUser.getId();
        tUser.setEditBy(currentLoginUserId);

        return tUserMapper.updateByPrimaryKeySelective(tUser);
    }

    @Override
    public int delUserById(Integer userId) {
        return tUserMapper.deleteByPrimaryKey(userId);
    }

    @Override
    public int batchDelUserByIds(List<String> idList) {
        return tUserMapper.deleteByIdList(idList);
    }

    @Override
    public List<TUserDO> getAllOwner() {
        return tUserMapper.selectByAll();
    }
}
